/**
 * Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef OHOS_GPUIMAGEFILTER_H
#define OHOS_GPUIMAGEFILTER_H
#include <GLES3/gl3.h>
#include <mutex>
#include <queue>
#include <string>

class GPUImageFilter {
public:
    GPUImageFilter();
    GPUImageFilter(const std::string vShader, const std::string fShader);
    ~GPUImageFilter();
    virtual void onInit();
    virtual void onInitialized();
    void ifNeedInit();
    void destroy();
    void onDestroy();
    virtual void onOutputSizeChanged(int width, int height);
    virtual void onDraw(int textureId, float *cubeBuffer, float *textureBuffer);
    bool isInitialized();
    int getOutputWidth();
    int getOutputHeight();
    int getProgram();
    int getAttribPosition();
    int getAttribTextureCoordinate();
    int getUniformTexture();

public:
    static const std::string NO_FILTER_VERTEX_SHADER;
    static const std::string NO_FILTER_FRAGMENT_SHADER;

protected:
    void onDrawArraysPre();
    void runPendingOnDrawTasks();
    void runOnDraw(std::function<void()> task);
    void setInteger(int location, int intValue);
    void setFloat(int location, float floatValue);
    void setFloatVec2(int location, float *floatArray);
    void setFloatVec3(int location, float *floatArray);
    void setFloatVec4(int location, float *floatArray);
    void setFloatArray(int location, size_t count, float *floatArray);
    void setPoint(int location, float *point);
    void setUniformMatrix3f(int location, float *matrix);
    void setUniformMatrix4f(int location, float *matrix);

private:
    void init();

private:
    std::string vertexShader;
    std::string fragmentShader;
    int glProgId = 0;
    int glAttribPosition;
    int glUniformTexture;
    int glAttribTextureCoordinate;
    int outputWidth;
    int outputHeight;
    bool initialized = false;
    std::queue<std::function<void()>> tasks;
    std::mutex mutex;
};
#endif // OHOS_GPUIMAGEFILTER_H
